package com.fhsk.file.common.utils.file;

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @Author tyx
 * @Date:2021.4.1
 */
@Slf4j
public class PdfUtil {

    /**
     * 将文件内容转成图片，并生成新的文件
     *
     * @param file  pdf文件
     * @param type  图片格式
     * @param scale 转换比例，数值越大越清晰
     */
    public static byte[] pdf2png(MultipartFile file, String type, float scale) {
        // 创建pdf文档
        Document iTextDoc = new Document(PageSize.A4, 0, 0, 0, 0);
        PDDocument doc = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            // pdf输出
            PdfWriter.getInstance(iTextDoc, byteArrayOutputStream);
            // 打开文档
            iTextDoc.open();

            // pdfbox加载文件
            doc = PDDocument.load(file.getBytes());
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                // 创建一页
                iTextDoc.newPage();

//                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI

                BufferedImage image = renderer.renderImage(i, scale);

                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
//				ImageIO.write(image, type, new File(outUrl));

                ByteArrayOutputStream nowBos = new ByteArrayOutputStream();
                ImageIO.write(image, type, nowBos);

                Image png = Image.getInstance(nowBos.toByteArray());
                float height = png.getHeight();
                float width = png.getWidth();
                int percent = getPercent2(height, width);
                png.setAlignment(Image.MIDDLE);
                png.scalePercent(percent + 3);// 表示是原来图像的比例;
                iTextDoc.add(png);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != iTextDoc) {
                iTextDoc.close();
            }

            if (null != doc) {
                try {
                    doc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return byteArrayOutputStream.toByteArray();
    }

    /**
     * 将文件内容转成图片，并生成新的文件
     *
     * @param bytes pdf文件
     * @param type  图片格式
     * @param scale 转换比例，数值越大越清晰
     */
    public static byte[] pdf2png(byte[] bytes, String type, float scale) {
        // 创建pdf文档
        Document iTextDoc = new Document(PageSize.A4, 0, 0, 0, 0);
        PDDocument doc = null;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            // pdf输出
            PdfWriter.getInstance(iTextDoc, byteArrayOutputStream);
            // 打开文档
            iTextDoc.open();

            // pdfbox加载文件
            doc = PDDocument.load(bytes);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                // 创建一页
                iTextDoc.newPage();

//                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI

                BufferedImage image = renderer.renderImage(i, scale);

                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
//				ImageIO.write(image, type, new File(outUrl));

                ByteArrayOutputStream nowBos = new ByteArrayOutputStream();
                ImageIO.write(image, type, nowBos);

                Image png = Image.getInstance(nowBos.toByteArray());
//                float height = png.getHeight();
//                float width = png.getWidth();
//                int percent = getPercent2(height, width);
//                png.setAlignment(Image.MIDDLE);
//                png.scalePercent(percent);// 表示是原来图像的比例;
                png.scaleAbsolute(PageSize.A4.getWidth(), PageSize.A4.getHeight());
                png.setAbsolutePosition(0, 0);

                iTextDoc.add(png);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != iTextDoc) {
                iTextDoc.close();
            }

            if (null != doc) {
                try {
                    doc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return byteArrayOutputStream.toByteArray();
    }

    public static byte[] pdf2png1(byte[] bytes, String type, float scale) throws IOException {
        // Load the PDF from byte array
        PDDocument document = PDDocument.load(bytes);
        PDFRenderer pdfRenderer = new PDFRenderer(document);

        // Create a new PDF document
        PDDocument newDocument = new PDDocument();

        try {
            // Define the A4 page size
            PDRectangle a4Rect = new PDRectangle(PDRectangle.A4.getWidth(), PDRectangle.A4.getHeight());

            // Iterate through each page and convert to image
//            PDPageTree allPages = document.getDocumentCatalog().getPages();
            for (int page = 0; page < document.getNumberOfPages(); ++page) {
//                BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300);
                BufferedImage bim = pdfRenderer.renderImage(page, scale);
                // Convert BufferedImage to byte array
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ImageIO.write(bim, type, baos);
                byte[] imageBytes = baos.toByteArray();
                baos.close();

                // Add the image to the new PDF document
                PDImageXObject pdImage = PDImageXObject.createFromByteArray(newDocument, imageBytes, "image");

                // Create a new A4 page
                PDPage newPage = new PDPage(a4Rect);
                newDocument.addPage(newPage);

                PDPageContentStream contentStream = new PDPageContentStream(newDocument, newPage);
                // Adjust the image size to fit the A4 page
                float newWidth = a4Rect.getWidth();
                float newHeight = a4Rect.getHeight();
                contentStream.drawImage(pdImage, 0, 0, newWidth, newHeight);
                contentStream.close();
            }

            // Save the new PDF document to a byte array
            ByteArrayOutputStream newPdfBytes = new ByteArrayOutputStream();
            newDocument.save(newPdfBytes);
            newDocument.close();
            return newPdfBytes.toByteArray();
        } finally {
            // Close the original PDF document
            document.close();
        }
    }

    /**
     * 将文件内容转成图片，并生成新的文件
     *
     * @param file   pdf文件
     * @param type   图片格式
     * @param outUrl 转换后存放路径
     * @param scale  转换比例，数值越大越清晰
     */
    public static void pdf2png(MultipartFile file, String type, String outUrl, float scale) {
        // 创建pdf文档
        Document iTextDoc = new Document(PageSize.A4, 0, 0, 0, 0);
        PDDocument doc = null;
        try {
            // pdf输出
            PdfWriter.getInstance(iTextDoc, new FileOutputStream(outUrl));
            // 打开文档
            iTextDoc.open();

            // pdfbox加载文件
            doc = PDDocument.load(file.getBytes());
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                // 创建一页
                iTextDoc.newPage();

//                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI

                BufferedImage image = renderer.renderImage(i, scale);

                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
//				ImageIO.write(image, type, new File(outUrl));

                ByteArrayOutputStream nowBos = new ByteArrayOutputStream();
                ImageIO.write(image, type, nowBos);

                Image png = Image.getInstance(nowBos.toByteArray());
                float height = png.getHeight();
                float width = png.getWidth();
                int percent = getPercent2(height, width);
                png.setAlignment(Image.MIDDLE);
                png.scalePercent(percent + 3);// 表示是原来图像的比例;
                iTextDoc.add(png);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != iTextDoc) {
                iTextDoc.close();
            }

            if (null != doc) {
                try {
                    doc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 将文件内容转成图片，并生成新的文件
     *
     * @param file   pdf文件
     * @param type   图片格式
     * @param outUrl 转换后存放路径
     */
    public static void pdf2png(MultipartFile file, String type, String outUrl) {
        // 创建pdf文档
        Document iTextDoc = new Document(PageSize.A4, 0, 0, 0, 0);
        PDDocument doc = null;
        try {
            // pdf输出
            PdfWriter.getInstance(iTextDoc, new FileOutputStream(outUrl));
            // 打开文档
            iTextDoc.open();

            // pdfbox加载文件
            doc = PDDocument.load(file.getBytes());
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                // 创建一页
                iTextDoc.newPage();

                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI

//                BufferedImage image = renderer.renderImage(i);

                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
//				ImageIO.write(image, type, new File(outUrl));

                ByteArrayOutputStream nowBos = new ByteArrayOutputStream();
                ImageIO.write(image, type, nowBos);

                Image png = Image.getInstance(nowBos.toByteArray());
                float height = png.getHeight();
                float width = png.getWidth();
                int percent = getPercent2(height, width);
                png.setAlignment(Image.MIDDLE);
                png.scalePercent(percent + 3);// 表示是原来图像的比例;
                iTextDoc.add(png);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != iTextDoc) {
                iTextDoc.close();
            }

            if (null != doc) {
                try {
                    doc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static int getPercent(float h, float w) {
        int p = 0;
        float p2 = 0.0f;
        if (h > w) {
            p2 = 297 / h * 100;
        } else {
            p2 = 210 / w * 100;
        }
        p = Math.round(p2);
        return p;
    }

    public static int getPercent2(float height, float weight) {
        float percent = 0.0F;
        if (height > weight) {
            percent = PageSize.A4.getHeight() / height * 100;
        } else {
            percent = PageSize.A4.getWidth() / weight * 100;
        }
        return Math.round(percent);
    }

    /**
     * 转换全部的pdf
     *
     * @param fileAddress 文件地址
     * @param filename    PDF文件名
     * @param type        图片类型
     */
    public static void pdf2png(String fileAddress, String filename, String type) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress + "\\" + filename + ".pdf");
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = 0; i < pageCount; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
                ImageIO.write(image, type, new File(fileAddress + "\\" + filename + "_" + (i + 1) + "." + type));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 自由确定起始页和终止页
     *
     * @param fileAddress  文件地址
     * @param filename     pdf文件名
     * @param indexOfStart 开始页  开始转换的页码，从0开始
     * @param indexOfEnd   结束页  停止转换的页码，-1为全部
     * @param type         图片类型
     */
    public static void pdf2png(String fileAddress, String filename, int indexOfStart, int indexOfEnd, String type) {
        // 将pdf装图片 并且自定义图片得格式大小
        File file = new File(fileAddress + "\\" + filename + ".pdf");
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for (int i = indexOfStart; i < indexOfEnd; i++) {
                BufferedImage image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // BufferedImage srcImage = resize(image, 240, 240);//产生缩略图
                ImageIO.write(image, type, new File(fileAddress + "\\" + filename + "_" + (i + 1) + "." + type));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
